package com.framework.loippi.controller.api;

import com.framework.loippi.api.utils.ApiUtils;
import com.framework.loippi.api.utils.Xerror;
import com.framework.loippi.cache.ConfigCache;
import com.framework.loippi.dto.api.params.WxParam;
import com.framework.loippi.entity.ImUser;
import com.framework.loippi.entity.ShareConfig;
import com.framework.loippi.entity.TUser;
import com.framework.loippi.entity.weixin.WxUserJson;
import com.framework.loippi.service.*;
import com.framework.loippi.service.weixin.WxUserService;
import com.framework.loippi.service.weixin.impl.WxBaseServiceImpl;
import com.framework.loippi.sms.AliyunSmsService;
import com.framework.loippi.support.APIPrincipal;
import com.framework.loippi.utils.RandomGUIDUtil;
import com.framework.loippi.utils.RandomUtils;
import com.framework.loippi.utils.StringUtils;
import com.framework.loippi.utils.tool.TLSSigAPIv2;
import io.swagger.annotations.*;
import okhttp3.*;
import org.json.simple.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 第三方登录
 *
 * @author wangcj
 * @version 2.0
 */
@Api(value = "用户登录注册模块", description = "用户登录注册模块", tags = "用户登录注册模块")
@Controller("apiAuthsController")
public class AuthsAPIController extends ApiBaseController {

    @Resource
    private RedisService redisService;

    @Resource
    private AreaService areaService;

    @Resource
    private WxUserService wxUserService;

    @Resource
    private TUserService tUserService;

    @Resource
    private WxBaseServiceImpl wxBaseService;

    @Resource
    private ShareConfigService shareConfigService;

    @Resource
    private ParameterSettingService parameterSettingService;

    @Resource
    private AliyunSmsService aliyunSmsService;

    @Resource
    private ImUserService imUserService;

//    @Resource
//    private IMService imService;
//
//    /**
//     * 手机号注册
//     *
//     * @param code     验证码
//     * @param areaId   地区id
//     * @param phone    手机号
//     * @param password 密码
//     * @return
//     */
//    @ApiOperation(value = "手机号注册", response = APIPrincipal.class, notes = "手机号注册", httpMethod = "POST", produces = "application/json")
//    @RequestMapping(value = "/api/auths/app/register.json", method = RequestMethod.POST)
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "form"),
//            @ApiImplicitParam(name = "areaId", value = "验证码", required = true, paramType = "form"),
//            @ApiImplicitParam(name = "phone", value = "验证码", required = true, paramType = "form"),
//            @ApiImplicitParam(name = "password", value = "验证码", required = true, paramType = "form")
//    })
//    @ApiResponses({
//            @ApiResponse(code = 1, message = "操作成功"),
//            @ApiResponse(code = 0, message = "操作失败")
//    })
//    public @ResponseBody
//    String register(String code, Long areaId, String phone, String password, String userInvite) {
//
//        if (null == code || "".equals(code) || null == phone || "".equals(phone) || null == password || "".equals(password) || null == areaId) {
//            return ApiUtils.error("参数错误");
//        }
//        String msgCode = redisService.get(phone, String.class);
//        if (null == msgCode || "".equals(msgCode) || !code.equals(msgCode)) {
//            return ApiUtils.error("验证码错误");
//        }
//
//        APIPrincipal principal = new APIPrincipal();
//        RandomGUIDUtil myGUID = new RandomGUIDUtil();
//        String sessionid = myGUID.valueAfterMD5;
//        principal.setAuthentication(APIPrincipal.getCacheKey(sessionid));
//        principal.setIsBindPhone(1);
//        redisService.save(APIPrincipal.getCacheKey(sessionid), principal);
//        //清除redis验证码缓存
//        redisService.delete(phone);
//        return ApiUtils.success(principal);
//    }

    /**
     * 短信登录
     *
     * @param mobile   手机号
     * @param code     短信验证码
     * @return
     */
    @ApiOperation(value = "短信登录", response = APIPrincipal.class, notes = "短信登录", httpMethod = "POST", produces = "application/json")
    @RequestMapping(value = "/api/auths/app/loginToMsg.json", method = {RequestMethod.POST}, produces = {"application/json;charset=UTF-8"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "form"),
            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, paramType = "form"),
    })
    @ApiResponses({
            @ApiResponse(code = 1, message = "操作成功"),
            @ApiResponse(code = 0, message = "操作失败")
    })
    public @ResponseBody
    String loginToMsg(String mobile, String code, String openId) {
        if (org.apache.commons.lang.StringUtils.isBlank(mobile)
                || org.apache.commons.lang.StringUtils.isBlank(code)
                || org.apache.commons.lang.StringUtils.isBlank(openId)) {
            return ApiUtils.error("参数错误");
        }
        TUser appUser = tUserService.findByOpenId(openId);
        if (null == appUser) {
            return ApiUtils.error("用户不存在！");
        }
        TUser mobileUser = tUserService.findByPhone(mobile);
        if (mobileUser != null) {
            return ApiUtils.error("该号码已绑定");
        }
        String msgCode = redisService.get(mobile, String.class);
        System.out.println("msgCode" +  msgCode);
        if (!msgCode.equals(code)) {
            return ApiUtils.error("验证码错误");
        } else {
            appUser.setPhone(mobile);
            tUserService.update(appUser);
        }
        APIPrincipal principal = new APIPrincipal();
        principal.setAvatar(appUser.getAvatar());
        principal.setId(appUser.getId());
        principal.setIsBindPhone(org.apache.commons.lang.StringUtils.isBlank(appUser.getPhone()) ? 0 : 1);
        principal.setNickName(appUser.getNickName());
        principal.setOpenId(appUser.getOpenId());
//      principal.setType(1);
        principal.setAccount(appUser.getPhone());
        principal.setGender(appUser.getGender());
        principal.setIsEnable(appUser.getIsEnable());

        redisService.delete(mobile);
        return ApiUtils.success(principal);
    }

//    /**
//     * 账号密码登录
//     *
//     * @param response
//     * @param mobile   手机号
//     * @param password 密码
//     * @return
//     */
//    @ApiOperation(value = "账号密码登录", response = APIPrincipal.class, notes = "账号密码登录", httpMethod = "POST", produces = "application/json")
//    @RequestMapping(value = "/api/auths/app/login.json", method = {RequestMethod.POST}, produces = "application/json;charset=UTF-8")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "form"),
//            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "form")
//    })
//    @ApiResponses({
//            @ApiResponse(code = 1, message = "操作成功"),
//            @ApiResponse(code = 0, message = "操作失败")
//    })
//    public @ResponseBody
//    String login() {
////        if (password == null || mobile == null || "".equals(password) || "".equals(mobile)) {
////            return ApiUtils.error("参数错误");
////        }
//        APIPrincipal principal = new APIPrincipal();
//        RandomGUIDUtil myGUID = new RandomGUIDUtil();
//        String sessionid = myGUID.valueAfterMD5;
//        System.out.println("haha");
//        System.out.println(sessionid);
//        principal.setOpenId("ovdM3xFo6i3zETor8nIdI6j13gQc");
//        principal.setAuthentication(APIPrincipal.getCacheKey(sessionid));
//        redisService.save(APIPrincipal.getCacheKey(sessionid), principal);
//        return ApiUtils.success(principal);
//    }

//    /**
//     * 第三方登录
//     *
//     * @param openId 第三方唯一id
//     * @param type   登录类型  1:微信，11:微信unionId，12：微信openid，2:QQ，3:微博
//     * @return
//     */
//    @ApiOperation(value = "第三方登录", response = APIPrincipal.class, notes = "第三方登录", httpMethod = "POST", produces = "application/json;charset=UTF-8")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "openId", value = "第三方唯一id", required = true, paramType = "form"),
//            @ApiImplicitParam(name = "type", value = "登录类型  1:微信，11:微信unionId，12：微信openid，2:QQ，3:微博", required = true, paramType = "form")
//    })
//    @ApiResponses({
//            @ApiResponse(code = 1, message = "操作成功"),
//            @ApiResponse(code = 0, message = "操作失败"),
//    })
//    @RequestMapping(value = "/api/auths/app/socialLogin.json", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
//    public @ResponseBody
//    String AuthsSocialLogin(WxParam param) {
//
//        String openId = param.getOpenId();
//        if (null == openId || "".equals(openId)) {
//            return ApiUtils.error("参数错误");
//        }
//        TUser tUser = tUserService.find("openId", openId);
//        if (null == tUser) {
//            return ApiUtils.error("用户不存在！");
//        }
//        String phone = param.getPhone();
//        if (phone != null || "".equals(phone)) {
//            TUser tUser1 = tUserService.find("phone", phone);
//            if (tUser1 != null) {
//                return ApiUtils.error("该号码已绑定");
//            } else {
//                tUser.setPhone(phone);
//                tUserService.update(tUser);
//            }
//        }
//        APIPrincipal principal = new APIPrincipal();
//        RandomGUIDUtil myGUID = new RandomGUIDUtil();
//        Map<String, Object> map = new HashMap<>();
//        String sessionid = myGUID.valueAfterMD5;
//        principal.setAuthentication(APIPrincipal.getCacheKey(sessionid));
//        principal.setAccount(openId);
//        principal.setId(tUser.getId());
//        principal.setIsBindPhone(StringUtil.isEmpty(tUser.getPhone())?0:1);
//        principal.setNickName(tUser.getNickName());
//        map.put("authentication", sessionid);
//        map.put("user", tUser);
//
//        redisService.save(APIPrincipal.getCacheKey(sessionid), principal);
//        return ApiUtils.success(map);
//    }

    /**
     * 第三方登录绑定手机号
     *
     * @param phone   手机号
     * @return
     */
    @ApiOperation(value = "第三方登录绑定手机号", response = APIPrincipal.class, notes = "第三方登录绑定手机号", httpMethod = "POST", produces = "application/json")
    @RequestMapping(value = "/api/auths/getCode.json", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", required = true, paramType = "form"),
    })
    @ApiResponses({
            @ApiResponse(code = 1, message = "操作成功"),
            @ApiResponse(code = 0, message = "操作失败"),
    })
    public @ResponseBody
    String getCode(String phone) {
        if (null == phone || "".equals(phone)) {
            return ApiUtils.error("参数错误");
        }
        aliyunSmsService.sendSmsTools(phone, phone);  //正式已测通
//        todo 短信发送
        APIPrincipal principal = new APIPrincipal();
        Map<String, String> map = new HashMap<>();
        RandomGUIDUtil myGUID = new RandomGUIDUtil();
        String sessionid = myGUID.valueAfterMD5;
        String cacheKey = APIPrincipal.getCacheKey(sessionid);
        principal.setAuthentication(cacheKey);
        redisService.save(cacheKey, principal);
        map.put("code", redisService.get(phone, String.class));
        return ApiUtils.success(map);
    }


//    /**
//     * 忘记密码-设置密码
//     *
//     * @param phone     手机号
//     * @param password  密码
//     * @param password2 密码2
//     * @return
//     */
//    @ApiOperation(value = "忘记密码-设置密码", response = ApiUtilsResult.class, notes = "忘记密码-设置密码", httpMethod = "POST", produces = "application/json")
//    @RequestMapping(value = "/api/auths/resetPassword.json", method = RequestMethod.POST)
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "phone", value = "手机号", required = true, paramType = "form"),
//            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "form"),
//            @ApiImplicitParam(name = "password2", value = "密码2", required = true, paramType = "form")
//    })
//    @ApiResponses({
//            @ApiResponse(code = 1, message = "操作成功"),
//            @ApiResponse(code = 0, message = "操作失败")
//    })
//    @ResponseBody
//    public String resetPassword(String phone, String password, String password2) {
//        if (null == password || "".equals(password) || null == password2 || "".equals(password2) || null == phone || "".equals(phone)) {
//            return ApiUtils.error("参数错误");
//        }
//        if (!StringUtil.isStringFilter(password)) {
//            return ApiUtils.error("密码只能是字母和数字");
//        }
//        return ApiUtils.error();
//    }


//    /**
//     * 小程序第三方登录
//     *
//     * @return
//     */
//    @ApiOperation(value = "小程序第三方登录", response = APIPrincipal.class, notes = "第三方登录", httpMethod = "POST", produces = "application/json")
//    @ApiResponses({
//            @ApiResponse(code = 1, message = "操作成功"),
//            @ApiResponse(code = 0, message = "操作失败"),
//            @ApiResponse(code = 40001, message = "获取微信授权失败"),
//    })
//    @RequestMapping(value = "/api/auths/app/appletLogin.json", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
//    public @ResponseBody
//    String appletSocialLogin(WxParam wxParam) {
//        WxUserJson userWxNum = wxUserService.getUSerWXNumForApplet(wxParam.getCode());
//        if (StringUtils.isNullOrEmpty(userWxNum.getOpenid())) {
//            return ApiUtils.error(Xerror.WECHAT_CODE_INVALID, "微信code无效");
//        }
//        System.out.println(wxParam.getEncryptedData());
//        System.out.println(userWxNum.getSession_key());
//        System.out.println(wxParam.getIv());
//        JSONObject userInfo = wxUserService.getUserInfo(wxParam.getEncryptedData(), userWxNum.getSession_key(), wxParam.getIv());
//        if (StringUtils.isNullOrEmpty(userInfo)) {
//            return ApiUtils.error(Xerror.USER_UNLOGIN_JSON_CODE, "获取微信授权失败");
//        }
//        System.out.println(userInfo);
//        String unionId = userInfo.getString("unionId");
//        String openId = userInfo.getString("openId");
//        String avatarUrl = userInfo.getString("avatarUrl");
//        String nickName = userInfo.getString("nickName");
//        APIPrincipal principal = new APIPrincipal();
//        RandomGUIDUtil myGUID = new RandomGUIDUtil();
//        String sessionid = myGUID.valueAfterMD5;
//        principal.setAuthentication(APIPrincipal.getCacheKey(sessionid));
//        redisService.save(principal.getAuthentication(), principal);
//        return ApiUtils.success(principal);
//    }


    /**
     * 微信公众号登录
     *
     * @return
     */
    @ApiOperation(value = "公众号登录", response = APIPrincipal.class, notes = "公众号登录", httpMethod = "POST", produces = "application/json;charset=UTF-8")
    @ApiResponses({
            @ApiResponse(code = 1, message = "操作成功"),
            @ApiResponse(code = 0, message = "操作失败"),
    })
    @RequestMapping(value = "/api/auths/app/public_login.json", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public @ResponseBody
    String publicSocialLogin(WxParam wxParam) {

        WxUserJson userWxNum = wxUserService.getUserWxNum(wxParam.getCode());
        if (StringUtils.isNullOrEmpty(userWxNum.getOpenid())) {
            return ApiUtils.error(Xerror.WECHAT_CODE_INVALID, "微信code无效");
        }
        //获取openId
        String openid = userWxNum.getOpenid();
        APIPrincipal principal = new APIPrincipal();
        RandomGUIDUtil myGUID = new RandomGUIDUtil();
        Map<String, Object> map = new HashMap<>();
        TUser openUser = new TUser();
        String sessionid = myGUID.valueAfterMD5;
        principal.setAuthentication(APIPrincipal.getCacheKey(sessionid));
        principal.setOpenId(openid);
        redisService.save(APIPrincipal.getCacheKey(sessionid), principal);
        if (openid != null && !"".equals(openid)) {
            WxUserJson userInfos = wxBaseService.getUserInfos(userWxNum.getOpenid(), userWxNum.getAccess_token());
            openUser = tUserService.findByOpenId(openid);
            if (openUser == null) {
                TUser appUser = new TUser();
//              保存获取的用户信息
                appUser.setOpenId(openid);

//              微信昵称乱码处理
                try {
                    appUser.setNickName(new String(userInfos.getNickname().getBytes("ISO-8859-1"),"UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                appUser.setGender(userInfos.getSex());
                appUser.setAvatar(userInfos.getHeadimgurl());
                TUser imUser = tUserService.findByOpenId(appUser.getOpenId());
//              将im用户持久化
                ImUser localImUser = new ImUser();
                try {
                    localImUser.setNickName(new String(userInfos.getNickname().getBytes("ISO-8859-1"),"UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                localImUser.setAvatar(userInfos.getHeadimgurl());
                localImUser.setCreateTime(new Date());
                imUserService.save(localImUser);
//              用户绑定im账号id
                appUser.setImUserId(localImUser.getId());
                tUserService.save(appUser);
//              调用腾讯im接口将用户注册到腾讯im
                MediaType mediaType = MediaType.get("application/json; charset=utf-8");
                OkHttpClient client = new OkHttpClient();
//              构造腾讯im导入用户资料参数
                String key = ConfigCache.getConfig("tx.im.key");
                Long sdkappid = Long.valueOf(ConfigCache.getConfig("tx.im.sdkappid"));
                String identifier = ConfigCache.getConfig("tx.im.identifier");
                String random = RandomUtils.getRandomNumberString(9);
                long expire = 180*24*3600;
                TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(sdkappid, key);
                String userSign = tlsSigAPIv2
                        .genSig(localImUser.getId().toString(),expire);
                localImUser.setUserSign(userSign);
                imUserService.update(localImUser);
                JSONObject json = new JSONObject();
                json.put("Identifier", localImUser.getId());//用户名
                json.put("Nick", localImUser.getNickName());//昵称
                json.put("FaceUrl", localImUser.getAvatar());//头像
                RequestBody body = RequestBody.create(String.valueOf(json), mediaType);
                Request request = new Request.Builder()
                        .url("https://console.tim.qq.com/v4/im_open_login_svc/account_import" +
                                "?sdkappid=" + sdkappid
                                + "&identifier=" + identifier
                                + "&usersig=" + userSign
                                + "&random=" + random
                                + "&contenttype=json")
                        .post(body)
                        .build();
                try (Response response = client.newCall(request).execute()) {
                    System.out.println(response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
//              用户没绑定手机设置info为false
                map.put("info", false);
                map.put("openId", openid);
                map.put("user", appUser);
                map.put("authentication",  principal.getAuthentication());
                ShareConfig shareConfig = shareConfigService.findByTime();
                map.put("shareConfig", shareConfig);
                return ApiUtils.success(map);
            } else if (null  == openUser.getPhone() || "".equals(openUser.getPhone())) {
                map.put("info", false);
                map.put("openId", openid);
                map.put("user", openUser);
                map.put("authentication",  principal.getAuthentication());
                ShareConfig shareConfig = shareConfigService.findByTime();
                map.put("shareConfig", shareConfig);
                System.out.println("print info");
                System.out.println(map.toString());
                return ApiUtils.success(map);
            } else {
                map.put("info", true);
                map.put("opeinId", openid);
                map.put("user", openUser);
                map.put("authentication",  principal.getAuthentication());
                ShareConfig shareConfig = shareConfigService.findByTime();
                map.put("shareConfig", shareConfig);
                return ApiUtils.success(map);
            }

        }
        return ApiUtils.error("获取openId失败");
    }


    public APIPrincipal getAuthenticationId(HttpServletRequest request) {
        String authenticationId = request.getHeader(APIPrincipal.PORPERTITY_AUTHENTICATION);
        if (null == authenticationId || "".equals(authenticationId)) {
            // 获取回话ID
            authenticationId = request.getParameter(APIPrincipal.PORPERTITY_AUTHENTICATION);
        }
        // 获取缓存实体
        APIPrincipal principal = redisService.get(authenticationId, APIPrincipal.class);
        return principal;
    }

    private String genUUIDRandom() {
        String string = UUID.randomUUID().toString();
        return string.replaceAll("-", "").substring(0, 30);
    }

    public static void main(String[] args) {
        AuthsAPIController authsAPIController = new AuthsAPIController();
//        authsAPIController.login();
    }

}
